<?php
/**
* Database auth plug-in for OnePress Community
*
* OnePress Version: 1.0.5
* 
* This is for authentication via the integrated user table
*
* @package login
* @version $Id: auth_op.php
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
	exit;
}

function init_op(){
}

// Provide option for WordPress path
function acp_op(&$new)
{
	// These are fields required in the config table
	$tpl = '
	<dl>
		<dt><label for="op_path">WordPress Path:</label><br /><span>This is the path to your WordPress installation relative to the site\'s root directory.  Most users will not need to change this.</span></dt>
		<dd><input type="text" id="op_path" size="40" name="config[op_path]" value="' . $new['op_path'] . '" /></dd>
	</dl>
	';
	
	return array(
		'tpl'		=> $tpl,
		'config'	=> array('op_path')
	);
}

/**
* Login function
*/
function login_op(&$username, &$password)
{
	global $db, $config;

	// do not allow empty password
	if (!$password)
	{
		return array(
			'status'	=> LOGIN_ERROR_PASSWORD,
			'error_msg'	=> 'NO_PASSWORD_SUPPLIED',
			'user_row'	=> array('user_id' => ANONYMOUS),
		);
	}

	if (!$username)
	{
		return array(
			'status'	=> LOGIN_ERROR_USERNAME,
			'error_msg'	=> 'LOGIN_ERROR_USERNAME',
			'user_row'	=> array('user_id' => ANONYMOUS),
		);
	}
	
	op_include_wp_module();
	
	global $current_user;
	
	op_WordPress::load();
	
	if(!defined('FROM_WP')){
		if(isset($current_user)){
			wp_clear_auth_cookie();
		}
	}

	if ( is_ssl() && force_ssl_login() && !force_ssl_admin() && ( 0 !== strpos($redirect_to, 'https') ) && ( 0 === strpos($redirect_to, 'http') ) )
		$secure_cookie = false;
	else
		$secure_cookie = '';
	
	if(!defined('FROM_WP') || defined('FROM_MW')){
		// Use the wp_signon method to get the object of our user from WP
		$wp_user = wp_signon(array(
			'user_login'	=> $username,
			'user_password'	=> 	html_entity_decode($password)
		), $secure_cookie);
		
		
		// Flag whether or not the user exists in wordpress
		$in_wp = isset($wp_user->errors['invalid_username']) || ($wp_user->ID == 0 && !isset($wp_user->errors['incorrect_password'])) ? FALSE: TRUE;
	}
	else{
		$wp_user = wp_get_current_user();
		$in_wp = $wp_user->ID == 0 ? FALSE : TRUE;
	}
	
	mysql_select_db($db->dbname);
	
	$sql = 'SELECT user_id, username, user_password, user_passchg, user_pass_convert, user_email, user_type, user_login_attempts
		FROM ' . USERS_TABLE . "
		WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
	$result = $db->sql_query($sql);
	$phpBB_user = $db->sql_fetchrow($result);
	$db->sql_freeresult($result);
	
	if($phpBB_user){
		$phpBB_authed = phpbb_check_hash($password, $phpBB_user['user_password']);
	}
	else{
		$phpBB_authed = false;
	}
	
	// TODO -- Make sure they are not in all modules active
	if ((!$phpBB_user || !$phpBB_authed) && !$in_wp)
	{
		
		// FIXME -- WordPress always reports username error when user exists in phpBB but not WP and password is wrong
		if(isset($wp_user->errors['incorrect_password']) || ($phpBB_user && !$phpBB_authed)){
			return array(
			'status'	=> LOGIN_ERROR_PASSWORD,
			'error_msg'	=> 'LOGIN_ERROR_PASSWORD',
			'user_row'	=> array('user_id' => ANONYMOUS),
			);
		}
		// error
		return array(
			'status'	=> LOGIN_ERROR_USERNAME,
			'error_msg'	=> 'LOGIN_ERROR_USERNAME',
			'user_row'	=> array('user_id' => ANONYMOUS),
		);
	}
	
	if(!$phpBB_user && ($in_wp || FROM_MW==TRUE)){
		require_once(TEMPLATEPATH.'/op/modules/module.wordpress.php');
		
		$email = $wp_user->user_email ? $wp_user->user_email : '';
		
		// since group IDs may change, use a query to make sure it is the right default group.
		$sql = 'SELECT group_id
				FROM ' . GROUPS_TABLE . "
				WHERE group_name = '" . $db->sql_escape(REGISTERED) . "'
					AND group_type = " . GROUP_SPECIAL;
		$result = $db->sql_query($sql);
		$row = $db->sql_fetchrow($result);
		$group_id = $row['group_id'];
		
		$user_row = array(
			'username' 	=> $username,
			'user_password' => phpbb_hash($password),
			'group_id'	=> 	$group_id,
			'user_email' => 	$email,
			'user_type' 	=>	0
		);
		
		$id = op_phpBB3::addUser($user_row);
		$phpBB_user = op_phpBB3::getUserById($id);
	}
	
	if((FROM_MW==TRUE || $phpBB_user) && !$in_wp){
		require_once(TEMPLATEPATH.'/op/modules/module.wordpress.php');
		
		$username = $phpBB_user['username'];
		
		$user_row = array(
			'username' 	=> $username,
			'email' => $phpBB_user['user_email'] ? $phpBB_user['user_email'] : '',
			'password' => html_entity_decode($password)
		);
		
		$wp_user = op_WordPress::addUser($user_row);
		
		$wp_user = wp_signon(array(
			'user_login'	=> $username,
			'user_password'	=> html_entity_decode($password)
		), $secure_cookie);
		
		mysql_select_db($db->db_name); // Select phpBB database
	}
	
	// If there are too much login attempts, we need to check for an confirm image
	// Every auth module is able to define what to do by itself...
	if ($config['max_login_attempts'] && $row['user_login_attempts'] >= $config['max_login_attempts'])
	{
		$confirm_id = request_var('confirm_id', '');
		$confirm_code = request_var('confirm_code', '');

		// Visual Confirmation handling
		if (!$confirm_id)
		{
			return array(
				'status'		=> LOGIN_ERROR_ATTEMPTS,
				'error_msg'		=> 'LOGIN_ERROR_ATTEMPTS',
				'user_row'		=> $row,
			);
		}
		else
		{
			global $user;

			$sql = 'SELECT code
				FROM ' . CONFIRM_TABLE . "
				WHERE confirm_id = '" . $db->sql_escape($confirm_id) . "'
					AND session_id = '" . $db->sql_escape($user->session_id) . "'
					AND confirm_type = " . CONFIRM_LOGIN;
			$result = $db->sql_query($sql);
			$confirm_row = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);

			if ($confirm_row)
			{
				if (strcasecmp($confirm_row['code'], $confirm_code) === 0)
				{
					$sql = 'DELETE FROM ' . CONFIRM_TABLE . "
						WHERE confirm_id = '" . $db->sql_escape($confirm_id) . "'
							AND session_id = '" . $db->sql_escape($user->session_id) . "'
							AND confirm_type = " . CONFIRM_LOGIN;
					$db->sql_query($sql);
				}
				else
				{
					return array(
						'status'		=> LOGIN_ERROR_ATTEMPTS,
						'error_msg'		=> 'CONFIRM_CODE_WRONG',
						'user_row'		=> $row,
					);
				}
			}
			else
			{
				return array(
					'status'		=> LOGIN_ERROR_ATTEMPTS,
					'error_msg'		=> 'CONFIRM_CODE_WRONG',
					'user_row'		=> $row,
				);
			}
		}
	}
	// Check password ...
	if (phpbb_check_hash($password, $phpBB_user['user_password']))
	{
		// Check for old password hash...
		if (strlen($phpBB_user['user_password']) == 32)
		{
			$hash = phpbb_hash($password);

			// Update the password in the users table to the new format
			$sql = 'UPDATE ' . USERS_TABLE . "
				SET user_password = '" . $db->sql_escape($hash) . "',
					user_pass_convert = 0
				WHERE user_id = {$phpBB_user['user_id']}";
			$db->sql_query($sql);

			$row['user_password'] = $hash;
		}
		
		if ($row['user_login_attempts'] != 0)
		{
			// Successful, reset login attempts (the user passed all stages)
			$sql = 'UPDATE ' . USERS_TABLE . '
				SET user_login_attempts = 0
				WHERE user_id = ' . $phpBB_user['user_id'];
			$db->sql_query($sql);
		}
		// User inactive...
		if ($phpBB_user['user_type'] == USER_INACTIVE || $phpBB_user['user_type'] == USER_IGNORE)
		{
			return array(
				'status'		=> LOGIN_ERROR_ACTIVE,
				'error_msg'		=> 'ACTIVE_ERROR',
				'user_row'		=> $phpBB_user,
			);
		}

		// Successful login... set user_login_attempts to zero...
		
		return array(
			'status'		=> LOGIN_SUCCESS,
			'error_msg'		=> false,
			'user_row'		=> $phpBB_user,
		);
	}
	
	// Password incorrect - increase login attempts
	$sql = 'UPDATE ' . USERS_TABLE . '
		SET user_login_attempts = user_login_attempts + 1
		WHERE user_id = ' . $phpBB_user['user_id'];
	$db->sql_query($sql);
	
	// Give status about wrong password...
	return array(
		'status'		=> LOGIN_ERROR_PASSWORD,
		'error_msg'		=> 'LOGIN_ERROR_PASSWORD',
		'user_row'		=> $phpBB_user,
	);
}

function logout_op(){
	if(defined('FROM_WP')) return;
	global $wpdb;

	op_include_wp_module();

	op_WordPress::logout();
	return;
}

function validate_session_op(){
	global $phpbb_root_path, $phpEx;
	// Need to block registrations for users that already exist
	$mode	= request_var('mode', '');


	/**
	 *  There's no hook for password changing in phpBB so we have to reuse validation technique from ucp_profile.php
	 */
	if($mode == 'reg_details' && !empty($_POST['submit'])){ // password and email changing
		global $auth, $config, $user;

		$data = array(
			'username'			=> utf8_normalize_nfc(request_var('username', $user->data['username'], true)),
			'email'				=> strtolower(request_var('email', $user->data['user_email'])),
			'email_confirm'		=> strtolower(request_var('email_confirm', '')),
			'new_password'		=> request_var('new_password', '', true),
			'cur_password'		=> request_var('cur_password', '', true),
			'password_confirm'	=> request_var('password_confirm', '', true),
		);
		
		// Do not check cur_password, it is the old one.
		$check_ary = array(
			'new_password'		=> array(
				array('string', true, $config['min_pass_chars'], $config['max_pass_chars']),
				array('password')),
			'password_confirm'	=> array('string', true, $config['min_pass_chars'], $config['max_pass_chars'])
		);

		if ($auth->acl_get('u_chgname') && $config['allow_namechange'])
		{
			$check_ary['username'] = array(
				array('string', false, $config['min_name_chars'], $config['max_name_chars']),
				array('username')
			);
		}

		if (sizeof(validate_data($data, $check_ary)))
			return true;
		if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && $data['password_confirm'] != $data['new_password'])
			return true;
		if (($data['new_password'] || ($auth->acl_get('u_chgemail') && $data['email'] != $user->data['user_email']) || ($data['username'] != $user->data['username'] && $auth->acl_get('u_chgname') && $config['allow_namechange'])) && !phpbb_check_hash($data['cur_password'], $user->data['user_password']))
			return true;	
			
		if ($auth->acl_get('u_chgemail') && $data['email'] != $user->data['user_email'] && $data['email_confirm'] != $data['email'])
			return true;
			
		op_include_wp_module();
				
		define('WP_ADMIN', true);
		op_WordPress::load();
		op_WordPress::loadAdminAPI();
		op_WordPress::updateUser($data);
	}

	if($mode != 'register' || !request_var('username', '', true)) return true;
	
	global $current_user;

	op_include_wp_module();
	
	op_WordPress::load();
	$username = utf8_normalize_nfc(request_var('username', '', true));
	
	if(op_userExists($username, 'phpbb')){
		// User exists, TODO -- notify user somehow
		//header('Location: http://www.opc.dev/forum/ucp.php?mode=register');
		redirect(append_sid("{$phpbb_root_path}index.$phpEx"));
	}
	else{
		return true;
	}
}

function op_include_wp_module(){
	$root_path = dirname(dirname(dirname(dirname(__FILE__))));

	// Determine path of WordPress installation
	global $config; // get config for op_path user option
	$extra_path = strlen($config['op_path']) > 0 ? $config['op_path'] : '';
	$extra_path = preg_replace('/^\/?(.*?[^\/$])\/*$/','$1/',$extra_path); // make sure path starts with no slash and ends with one slash
	$full_path = $root_path.'/'.$extra_path.'wp-content/themes/onepress/op/modules/module.wordpress.php';
	if(file_exists($full_path)){
		require($full_path);
	}
	else{
		error_log('Could not load WordPress module from '.$full_path); // log error
		echo <<<EOS
		<b>Error</b>. Could not load WordPress module.<br/>
		Module is set to be loaded from: <i>$full_path</i>.<br/>
		If this path is not correct, please edit the "WordPress Path" setting in the phpBB administration menu.
EOS;
		die;
	}
}

?>